/**
 *  Libevent tcp server 示例
 */


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <event2/event.h>
#include <event2/listener.h>
#include <event2/bufferevent.h>



#define SERVER_PORT 			9090

// 读缓冲区回调
void readcb(struct bufferevent * bev, void * ctx)
{
	char data_buf[1024] = {0};
	bufferevent_read(bev, data_buf, 1024);

	printf("Recv data: %s\n", data_buf);

	bufferevent_write(bev, data_buf, strlen(data_buf) + 1);	// 将数据反射到客户端


}

// 写缓冲区回调
void writecb(struct bufferevent * bev, void * ctx)
{
	printf("数据发送完成\n");
}



// 事件回调
void eventcb(struct bufferevent * bev, short what, void * ctx)
{
	if (what & BEV_EVENT_EOF)
    {
        printf("connection closed\n");  
    }
    else if(what & BEV_EVENT_ERROR)   
    {
        printf("some other error\n");
    }
    
    bufferevent_free(bev);    
    printf("buffevent 资源已经被释放...\n"); 
}


// 新连接回调
void listener_cb(struct evconnlistener * listener, evutil_socket_t fd, struct sockaddr * addr, int socklen, 
	void * ptr)
{
	struct event_base * base = (struct event_base *)ptr;
	struct bufferevent * bufev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE);	// 添加新事件
	
	bufferevent_setcb(bufev, readcb, writecb, eventcb, NULL); // 给 bufferevent 缓冲区设置回调
	bufferevent_enable(bufev, EV_READ);	// 启用读取事件，默认情况下，读取不启用，写入时间默认启用
}


int main()
{
	// 初始服务器地址
	struct sockaddr_in serverAddr;
	int socklen = sizeof(serverAddr);
	memset(&serverAddr, 0, socklen);
	serverAddr.sin_family = AF_INET;
	serverAddr.sin_port = htons(SERVER_PORT);
	serverAddr.sin_addr.s_addr = htonl(INADDR_ANY);

	struct event_base * base = event_base_new();
	// 创建套接字、绑定、监听接收连接请求
	struct evconnlistener * listener = evconnlistener_new_bind(base, listener_cb, base, 
		LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE, -1, (struct sockaddr *) &serverAddr, socklen);
	event_base_dispatch(base);


	evconnlistener_free(listener);
	event_base_free(base);

	return 0;


}


